//Task.cpp
//This cpp file deals with the creation and adjustment of task
//@author A0101038Y
//@class Task

#include "Task.h"

string Task::sendStatusTask(STATUS_TYPE_TASK status) const { //sending status for Task to enable done/not done/overdue status
	switch (status){
		case DONE:
			return STATUS_DONE;
			break;
		case NOT_DONE:
		default:
			return STATUS_NOT_DONE;
			break;
		case OVERDUE:
			return STATUS_OVERDUE;
			break;
	}
}
Task::Task(void): _statusCompleted(false)
{
	_entryType = TYPE_ENTRY;
}
Task::Task(string name, QDate endDate, QTime endTime, bool statusCompleted) : Entry(name, endDate, endTime), _statusCompleted(statusCompleted) {
	_entryType= TYPE_ENTRY;
	//set default case if storage text is edited by user that cause missing date or time.
	setDefaultForMissingEndDateTime();
}
Task::Task(const Entry* other): Entry(other->getName(), other->getEndDate(), other->getEndTime()), _statusCompleted(other->getStatus()) {
	_entryType= TYPE_ENTRY;
	//set default case if storage text is edited by user that cause missing date or time.
	setDefaultForMissingEndDateTime();
}
Task::~Task(void)
{
}
string Task::toString() { //loading of vector of strings to string for storing
	char buffer[1000];
	sprintf_s(buffer, MSG_OUTPUT.c_str(), 
		TYPE_ENTRY.c_str(), getName().c_str(), 
		getEndDate().toString(FORMAT_DATE).toStdString().c_str(),getEndTime().toString(FORMAT_TIME).toStdString().c_str(), _statusCompleted);
	return buffer;
}
Task Task::fromString(string input) { //loading of strings from storage file to vector of string 
	istringstream inStream(input);
	string name;
	string endDate;
	string endTime;
	string dump;
	bool statusCompleted;
	getline(inStream, dump, ' ');
	getline(inStream, name);
	getline(inStream, dump, ' ');
	getline(inStream, endDate);
	getline(inStream, dump, ' ');
	getline(inStream, endTime);
	getline(inStream, dump, ' ');
	inStream >> statusCompleted;
	return Task(name, QDate::fromString(QString::fromStdString(endDate), FORMAT_DATE), QTime::fromString(QString::fromStdString(endTime), FORMAT_TIME), statusCompleted);
}
bool Task::operator==(Entry* input) {
	return (getName()==input->getName() &&
		getEndDate()==input->getEndDate() &&
		getEndTime()==input->getEndTime() &&
		getStatus()==input->getStatus() &&
		getEntryType()==input->getEntryType());
}

bool Task::NotDoneOrOverdue () const { //enable identification of Not Done or Overdue (Not Done task past stipulated deadline)
		QDate const currentDate = QDate::currentDate();
		QTime const currentTime = QTime::currentTime();
		QDate const taskEndDate = getEndDate();
		QTime const taskEndTime = getEndTime();
		QDateTime const currentDateTime(currentDate, currentTime);
		QDateTime const taskDateTime(taskEndDate,taskEndTime); 
		return((taskDateTime > currentDateTime) ? 1 : 0);
}

string Task::setNotDoneOrOverdue () const { //setting of Not Done or Overdue status
	return ((NotDoneOrOverdue()) == true? sendStatusTask(NOT_DONE) : sendStatusTask(OVERDUE));
}

bool Task::setDone() { //setting of Done status.
	if(_statusCompleted) {
		_statusCompleted = false;
	} else {
		_statusCompleted = true;
	}
	return _statusCompleted;
}
bool Task::getStatus() const {
	return _statusCompleted;
}
string Task::getStatusString() const {
	if(_statusCompleted){
		return sendStatusTask(DONE);
	} else{
		return setNotDoneOrOverdue();
	}
}
string Task::getEntryType() const {
	return _entryType;
}
int Task::getAttributeCount() const {
	return Task::NUM_ATTRIBUTES;
}
string Task::getSearchString() const{ //searching of string
	char buffer[1000];
	sprintf_s(buffer ,SEARCH_PLACEHOLDER, getName().c_str(), getEndDate().toString(SEARCH_DATE_FORMAT).toStdString().c_str(), getEndTime().toString(SEARCH_TIME_FORMAT).toStdString().c_str(), getStatusString().c_str());
	return buffer;
}
void Task::setDefaultForMissingEndDateTime(){ //set default case for end date and time if .txt storage file is altered by user.
	if(getEndDate().isValid() && getEndTime().isValid()){
		return;
	} else {
		if(!getEndDate().isValid() && getEndTime().isValid()){
			//handle case where storage text is altered such that end date is missing. Set it to current date
			setDefaultEndDate();
		} else {
			if(!getEndTime().isValid() && getEndDate().isValid()){
				////handle case where storage text is altered such that end time is missing. Set it to 0000hrs
				setDefaultEndTime();
			} else {
				if(!getEndTime().isValid() && !getEndDate().isValid()){
					////handle case where storage text is altered such that end date and time are missing. Set it to current date 0000hrs
					setDefaultEndDateTime();
				} else {
					return;
				}
			}
		}
	}
}
void Task::setDefaultEndDate(){ //setting default end date for missing end date
	_endDate = QDate::currentDate();
}
void Task::setDefaultEndTime(){ //setting default end time for missing end time
	_endTime = QTime::QTime(00,00);
}
void Task::setDefaultEndDateTime(){ //setting default end date and time for missing end date and time
	_endDate = QDate::currentDate();
	_endTime = QTime::QTime(00,00);
}
//void Task::setName(string name) {
//	Entry::setName(name);
//}
const string Task::MSG_OUTPUT= "%s\nNAME: %s\nDUE_DATE: %s\nDUE_TIME: %s\nSTATUS: %d\n";
const string Task::TYPE_ENTRY= "TASK";
const string Task::STATUS_DONE= "Done";
const string Task::STATUS_NOT_DONE="Not Done";
const string Task::STATUS_OVERDUE="Overdue";
const char* Task::SEARCH_PLACEHOLDER= "%s %s %s %s";
const char* Task::SEARCH_DATE_FORMAT="dddd MMMM yyyy dd/MM/yy dd/MM/yyyy dd/M/yy dd/M/yyyy";
const char* Task::SEARCH_TIME_FORMAT="h:mm hmmap H:mm Hmm";